import { CSSProperties } from "react";
import { create } from "zustand";

/* 
- id: 唯一标识符。
- name: 组件名称。
- props: 组件的属性（任意类型）。
- children: 可选字段，用于存储子组件数组，构成树形结构。
- parentId: 可选字段，记录该组件的父组件 ID。
*/
export interface Component {
    id: number;
    name: string;
    desc:string;
    props: any;
    styles?:CSSProperties;
    children?: Component[];
    parentId?: number;
}
// components: Component 数组，代表所有组件的树形结构。
interface State {
    components: Component[];
    mode:"edit"|"preview";
    curComponentId?:number | null; 
    curComponent:Component | null;
}

/* 
- addComponent: 增加组件，可以指定父组件（parentId）以支持嵌套结构。
- deleteComponent: 根据组件 ID 删除特定组件。
- updateComponentProps: 更新指定组件的 props。
*/
interface Action {
    addComponent: (component: Component, parentId?: number) => void;
    deleteComponent: (componentId: number) => void;
    updateComponentProps: (componentId: number, props: any) => void;
    setCurComponentId: (componentId:number | null) => void;
    updateComponentStyles: (componentId: number, styles: CSSProperties , replace?:boolean) => void;
    setMode:(mode:State["mode"]) => void
}

export const useComponetsStore = create<State & Action>((set, get) => ({
    components: [
        {
            id: 1,
            name: "Page",
            props: {},
            desc: "页面",
        },
    ],
    curComponent:null,
    curComponentId:null,
    setCurComponentId:(componentId) => set((state)=> ({
        curComponent:getComponentById(componentId , state.components),
        curComponentId:componentId
    })),
    mode:"edit",
    setMode:(mode) => set({mode}),
    // 添加组件  
    // 将新的 component 添加到 components 数组中。若指定了 parentId，则尝试将 component 添加为指定父组件的子组件。
    addComponent: (component, parentId) => set((state) => {
        /* 
        - 检查 parentId 是否存在。
        - 若存在，调用辅助函数 getComponentById 查找父组件。
        - 若找到父组件，将 component 添加到 parentComponent.children 中，并设置 component.parentId。
        - 若未指定 parentId，直接将 component 作为根组件添加到 components 数组末尾。 
        */
        if (parentId) {
            const parentComponent = getComponentById(
                parentId,
                state.components
            );
            if (parentComponent) {
                if (parentComponent.children) {
                    parentComponent.children.push(component);
                } else {
                    parentComponent.children = [component];
                }
            }

            component.parentId = parentId;
            return { components: [...state.components] };
        }
        return { components: [...state.components, component] };
    }),
    // 根据 componentId 删除指定的组件
    deleteComponent: (componentId) => {
        if (!componentId) return;
        const component = getComponentById(componentId, get().components);
        /* 
        - 使用 getComponentById 查找要删除的组件及其父组件。
        - 若 component 存在并且有 parentId，则查找其父组件，并将目标组件从 children 数组中移除。
        - 使用 set 更新 components 状态。
        */
        if (component?.parentId) {
            const parentComponent = getComponentById(
                component.parentId,
                get().components
            );
            if (parentComponent) {
                parentComponent.children = parentComponent?.children?.filter(
                    (item) => item.id !== +componentId
                );
                set({ components: [...get().components] });
            }
        }
    },
    // 更新指定组件的 props
    updateComponentProps: (componentId, props) =>set((state) => {
        /* 
        - 使用 getComponentById 查找 componentId 对应的组件。
        - 若找到组件，则将其 props 进行浅合并更新。
        - 使用 set 更新 components 状态，确保变更生效
        */
        const component = getComponentById(componentId, state.components);
        if (component) {
            component.props = { ...component.props, ...props };
            return { components: [...state.components] };
        }
        return { components: [...state.components] };
    }),
    // 更新指定组件样式
    updateComponentStyles: (componentId, styles , replace) => set((state) => {
        const component = getComponentById(componentId, state.components);
        if (component) {
            component.styles = replace ? {...styles} : {...component.styles, ...styles};
            return {components: [...state.components]};
        }
        return {components: [...state.components]};
    })   
}));

/*
递归遍历 components 树，查找匹配的组件 ID。
- 逐层递归遍历 components 及其子组件 children，返回找到的组件。
- 若无匹配项，则返回 null。
*/
export function getComponentById(
    id: number | null,
    components: Component[]
): Component | null {
    if (!id) return null;

    for (const component of components) {
        if (component.id == id) return component;
        if (component.children && component.children.length > 0) {
            const result = getComponentById(id, component.children);
            if (result !== null) return result;
        }
    }
    return null;
}
